﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Thauan_Juliano_World
{
    public class Tree : WorldObject
    {
        private GameObject tree;

        private int xScale = 6;
        private int yScale  = 10;

        private Vector3 position = new Vector3(0, 0, 0);
        private Vector3 scale = new Vector3(5, 10, 0);

        private List<GameObject> gameObjects = new List<GameObject>();
        private List<Tree> worldObjects;

        private BasicEffect effect;
        private GraphicsDevice gd;

        private Camera mainCamera;

        public Tree(List<Tree> worldObjects, Vector3 position, Texture2D texture, Camera mainCamera)
        {
            this.worldObjects = worldObjects;
            this.gd = Inventory.getGraphicsDevice();
            this.effect = Inventory.getBasicEffect();
            this.mainCamera = mainCamera;

            this.position = position;

            // --------------------------------- === ----------------------------------- //

            int tmpxScale = xScale / 2;
            int tmpyScale = yScale / 2;
            VertexPositionTexture[] verts = new VertexPositionTexture[4];
            verts[0] = new VertexPositionTexture(new Vector3(-tmpxScale, -tmpyScale, 0), new Vector2(0, 1));
            verts[1] = new VertexPositionTexture(new Vector3(-tmpxScale, tmpyScale, 0), new Vector2(0, 0));
            verts[2] = new VertexPositionTexture(new Vector3(tmpxScale, -tmpyScale, 0), new Vector2(1, 1));
            verts[3] = new VertexPositionTexture(new Vector3(tmpxScale, tmpyScale, 0), new Vector2(1, 0));

            this.tree = new GameObject(verts, 0, 2, gameObjects, Matrix.Identity, this.position, texture);
            this.tree.alpha = 0;

            // --------------------------------- === ----------------------------------- //
            this.worldObjects.Add(this);

        }

        public void SetRotation() 
        {
            // ======  Warning ======

            float x = -this.position.X + mainCamera.positions[0].X;
            float y = this.position.Z - mainCamera.positions[0].Z;

            if (y > 0)
            {
                // I Quadrante
                if (x > 0)
                {
                    double radians = Math.Atan2(y, x);
                    double angle = radians * (180 / MathHelper.Pi);
                    //Log.Debug(radians.ToString() + " " + angle.ToString());

                    double treeAngle = angle + 180;
                    double treeRadians = treeAngle * (MathHelper.Pi / 180) - MathHelper.Pi / 180 * 90;
                    //Log.Debug(treeRadians.ToString() + " " + treeAngle.ToString() + " I Quadrante");
                    this.tree.world = Matrix.CreateRotationY((float)treeRadians);

                }
                // II Quadrante
                else 
                {
                    double radians = Math.Atan2(y, x);
                    double angle = radians * (180 / MathHelper.Pi);
                    //Log.Debug(radians.ToString() + " " + angle.ToString());

                    double treeAngle = angle + 180;
                    double treeRadians = treeAngle * (MathHelper.Pi / 180) - MathHelper.Pi / 180 * 90;
                    //Log.Debug(treeRadians.ToString() + " " + treeAngle.ToString() + " II Quadrante");
                    this.tree.world = Matrix.CreateRotationY((float)treeRadians);

                }
            }
            else if(y < 0)
            {
                // IV Quadrante
                if (x > 0)
                {
                    double radians = Math.Atan2(y, x);
                    double angle = radians * (180 / MathHelper.Pi);
                    //Log.Debug(radians.ToString() + " " + angle.ToString() + " IV Quadrante");

                    double treeAngle = angle + 180;
                    double treeRadians = treeAngle * (MathHelper.Pi / 180) - MathHelper.Pi / 180 * 90;
                    //Log.Debug(treeRadians.ToString() + " " + treeAngle.ToString() + " II Quadrante");
                    this.tree.world = Matrix.CreateRotationY((float)treeRadians);

                }
                // III Quadrante
                else
                {
                    double radians = Math.Atan2(y, x);
                    double angle = radians * (180 / MathHelper.Pi);
                    //Log.Debug(radians.ToString() + " " + angle.ToString() + " III Quadrante");

                    double treeAngle = angle + 180;
                    double treeRadians = treeAngle * (MathHelper.Pi / 180) - MathHelper.Pi / 180 * 90;
                    //Log.Debug(treeRadians.ToString() + " " + treeAngle.ToString() + " II Quadrante");
                    this.tree.world = Matrix.CreateRotationY((float)treeRadians);

                }
            }
        }
        public override void Update()
        {
            
        }

        public override void Draw()
        {
            foreach (GameObject go in gameObjects)
            {

                go.world = Matrix.Invert(mainCamera.View);

                go.SetPosition();
                effect.World = go.world;

                go.SetForWath();

                if (go.isForTexture())
                {
                    effect.Texture = go.texture;
                    Inventory.getGraphicsDevice().SamplerStates[0] = SamplerState.LinearClamp;

                    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Apply();

                        this.gd.DrawUserPrimitives<VertexPositionTexture>
                        (go.pt, go.vertsTexture, go.offset, go.count);
                    }
                }
                else
                {
                    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Apply();

                        this.gd.DrawUserPrimitives<VertexPositionColor>
                        (go.pt, go.verts, go.offset, go.count);
                    }
                }
                go.ResetPosition();
            }
        }

        public void SetPosition(Vector3 position) 
        {
            this.position = position;
            this.tree.position = position;
        }
        public override void Destroy()
        {
            try { this.worldObjects.Remove(this); }
            catch (Exception e)
            {
                Console.WriteLine("Erro: " + e);
            }
        }

        public List<GameObject> getObjects() 
        {
            return this.gameObjects;
        }
    }
}

